/**
 * 
 */
package com.novartis.nims.imagedc.logic;

import java.io.IOException;
import java.net.URI;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import com.pixelmed.dicom.DicomException;

/**
 * The Scan class contains a Set of {@link ImageResource}s which constitute the
 * Scan. It delegates adding and iteration of images to the backing Set. It
 * also defines a query mechanism to retrieve DICOM attribute values from the
 * scan ({@link #getAttributeValue(AttributeTagDelegate)}). This mechanism
 * makes no guarantee on which of the underlying images the value is retrieved
 * from, or on whether it is consistent across images.
 * <p>
 * This class implements <code>Iterable<ImageResource></code> as a means for
 * clients to access the image set. Clients must be careful not to add any
 * images during iteration. The only way to remove images is through the
 * {@link java.util.Iterator#remove()} method.
 * 
 * @author Josh Snyder
 */
public class Scan implements Iterable<ImageResource> {
	
	private Set<ImageResource> imageSet = new HashSet<ImageResource>();
	
	private URI basePath;

	private String studyId;

	private String siteSubjectId;
	private String visitNumber;
	private String visitRepeatNumber;
	private String visitName;

	private String scanName;
	private String scanRepeatNumber;
	private String scanKey;

	/**
	 * Constructs a <code>Scan</code> initially devoid of images.
	 */
	public Scan() {	}
	
	/**
	 * Returns an <code>Iterator</code> over the contained images. Images can only be
	 * removed by means of this iterator.
	 * 
	 * @return an Iterator over the images contained in this Scan
	 * @see java.lang.Iterable#iterator()
	 */
	public Iterator<ImageResource> iterator() {
		return imageSet.iterator();
	}

	/**
	 * Returns the number of <code>ImageResource</code>s stored in this <code>
	 * Scan</code>
	 * 
	 * @return the number of images in this scan
	 */
	public int size() {
		return imageSet.size();
	}

	/**
	 * Adds the specified image to this scan if it is not already present.
	 * 
	 * @param image the {@link ImageResource} to add
	 */
	public void addImage(ImageResource image) {
		imageSet.add(image);
	}

	/**
	 * Adds all of the images in the specified collection to this scan if
	 * they're not already present.
	 * 
	 * @param theImageFiles the collection containing images to be added to
	 * this scan
	 */
	public void addAllImageFiles(Collection<ImageResource> theImageFiles) {
		imageSet.addAll(theImageFiles);
	}

	/**
	 * Gets the DICOM attribute value for the specified tag from the scan
	 * ({@link #getAttributeValue(AttributeTagDelegate)}). This method makes
	 * no guarantee on which of the underlying images the value is retrieved
	 * from, or on whether it is consistent across images. If there is more
	 * than one string value, only the first is returned. If there is no
	 * string value, the value is absent, or it cannot be read for some
	 * reason, an empty string is returned. If there are no images in the scan,
	 * a null value is returned.
	 * <p>
	 * A canonicalized (unpadded) form is returned, not the original string.
	 * 
	 * @param tag
	 * @return the first attribute value from an arbitrary image, or null if
	 * there are no images
	 */
	public String getAttributeValue(AttributeTagDelegate tag) {
		String value = null;
		
		Iterator<ImageResource> iterator = imageSet.iterator();
		if (iterator.hasNext()) {
			ImageResource image = iterator.next();
			
			try {
				value = image.getAttributeValue(tag, false);
			} catch (IOException e) {
				//TODO: try next file?
			} catch (DicomException e) {
				//TODO: try next file?
			}
		}
		return value;
	}

	public void setScanKey(String value) {
		scanKey = value;
	}

	public String getScanKey() {
		return scanKey;
	}

	public void setScanName(String value) {
		scanName = value;
	}

	public String getScanName() {
		return scanName;
	}

	public void setScanRepeatNumber(String value) {
		scanRepeatNumber = value;
	}

	public String getScanRepeatNumber() {
		return scanRepeatNumber;
	}

	public String getSiteSubjectId() {
		return siteSubjectId;
	}

	public void setSiteSubjectId(String value) {
		siteSubjectId = value;
	}
	
	public String getVisitNumber() {
		return visitNumber;
	}

	public void setVisitNumber(String value) {
		visitNumber = value;
	}
	
	public String getVisitRepeatNumber() {
		return visitRepeatNumber;
	}

	public void setVisitRepeatNumber(String value) {
		visitRepeatNumber = value;
	}

	public String getVisitName() {
		return visitName;
	}

	public void setVisitName(String value) {
		visitName = value;
	}
	
	public String getStudyId() {
		return studyId;
	}

	public void setStudyId(String value) {
		studyId = value;
	}

	public URI getBasePath() {
		return basePath;
	}

	public void setBasePath(URI value) {
		basePath = value;
	}

}
